package com.platform.feign.spring.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import feign.RequestTemplate;
import feign.Util;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Objects;

/**
 * @author hgx
 * 中台feign编码器
 */
@Component
public class PlatformFeignEncoder implements Encoder {

    @Resource
    @Qualifier("platformFeignFastJsonConfig")
    private FastJsonConfig platformFastJsonConfig;

    private final SpringFormEncoder springFormEncoder = new SpringFormEncoder();


    @Override
    public void encode(Object requestBody, Type bodyType, RequestTemplate template) throws EncodeException {

        Collection<String> contentTypes = template.headers().get("Content-Type");

        MediaType requestContentType = null;
        if (contentTypes != null && !contentTypes.isEmpty()) {
            String type = contentTypes.iterator().next();
            requestContentType = MediaType.valueOf(type);
        }

        if (bodyType != null && bodyType.equals(MultipartFile.class)) {
            if (Objects.equals(requestContentType, MediaType.MULTIPART_FORM_DATA)) {
                springFormEncoder.encode(requestBody, bodyType, template);
                return;
            }
            else {
                String message = "Content-Type \"" + MediaType.MULTIPART_FORM_DATA
                        + "\" not set for request body of type "
                        + requestBody.getClass().getSimpleName();
                throw new EncodeException(message);
            }
        }

        byte[] bytes = JSON.toJSONBytes(requestBody, platformFastJsonConfig.getSerializeConfig(), platformFastJsonConfig.getSerializeFilters(), platformFastJsonConfig.getDateFormat(), JSON.DEFAULT_GENERATE_FEATURE, platformFastJsonConfig.getSerializerFeatures());
        template.body(bytes, Util.UTF_8);
    }
}
